﻿using FySystem.Extension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;

namespace FySystem.IO
{
    /// <summary>
    /// 有点类似json，主要用于将对象比较快的转换为byte数组，与FyCache结合用
    /// </summary>
    public class CSon
    {
        public enum CSonTypes
        {
            Value = 0,
            CObject = 1,
            CArray = 2
        }

        /*
         * Byte=0,
            ByteArray=1,
            Boolean=2,
            String=3,
            Short=4,
            UShort=5,
            Int=6,
            UInt=7,
            Long=8,
            ULong=9,
            Float=10,
            Double=11,
            Decimal=12,
            DateTime=13
         * */
        private byte _valueType = 0x00;

        public CSonTypes CSonType { get; private set; }

        /// <summary>
        /// 当CSon作为子项时不能为null，要用CSonValueNull，否则调用ToBytes()时会抛错
        /// </summary>
        public static CSonValueNull CSonValueNull = new CSonValueNull();
        /// <summary>
        /// 当CSon作为子项时不能为null，要用CSonObjectNull，否则调用ToBytes()时会抛错
        /// </summary>
        public static CSonObjectNull CSonObjectNull = new CSonObjectNull();
        /// <summary>
        /// 当CSon作为子项时不能为null，要用CSonArrayNull，否则调用ToBytes()时会抛错
        /// </summary>
        public static CSonArrayNull CSonArrayNull = new CSonArrayNull();

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="cSonTypes"></param>
        public CSon(CSonTypes cSonTypes)
        {
            CSonType = cSonTypes;
        }

        private CSon(byte[] bValue)
        {
            CSonType = CSonTypes.Value;
            _bvalue = bValue;
        }

        private CSon(CSonValueNull cnull)
        {
            CSonType = CSonTypes.Value;
            _valueType = 0xff;
            _bvalue = null;
        }

        private CSon(CSonObjectNull cnull)
        {
            CSonType = CSonTypes.CObject;
            _bvalue = null;
        }

        private CSon(CSonArrayNull cnull)
        {
            CSonType = CSonTypes.CArray;
            _array = null;
        }

        /******************************* 作为值时 **********************************/
        private byte[] _bvalue = null;

        public static implicit operator CSon(byte value) => new CSon(new byte[] { value }) { _valueType = 0 };
        public static implicit operator CSon(byte[] value) => new CSon(value) { _valueType = 1 };
        public static implicit operator CSon(bool value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 2 };
        public static implicit operator CSon(string value) => new CSon(Encoding.UTF8.GetBytes(value == null?"":value)) { _valueType = 3 };
        public static implicit operator CSon(short value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 4 };
        public static implicit operator CSon(ushort value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 5 };
        public static implicit operator CSon(int value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 6 };
        public static implicit operator CSon(uint value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 7 };
        public static implicit operator CSon(long value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 8 };
        public static implicit operator CSon(ulong value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 9 };
        public static implicit operator CSon(float value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 10 };
        public static implicit operator CSon(double value) => new CSon(BitConverter.GetBytes(value)) { _valueType = 11 };
        public static implicit operator CSon(decimal value) => new CSon(ToBytes(value)) { _valueType = 12 };
        public static implicit operator CSon(DateTime value) => new CSon(BitConverter.GetBytes(value.Ticks)) { _valueType = 13};
        public static implicit operator CSon(CSonValueNull value) => new CSon(value);
        public static implicit operator CSon(CSonObjectNull value)=>new CSon(value);
        public static implicit operator CSon(CSonArrayNull value)=>new CSon(value);

        public static explicit operator byte?(CSon value) => value.ByteValue;
        public static explicit operator byte[](CSon value) => value.BytesValue;
        public static explicit operator bool?(CSon value) => value.BooleanValue;
        public static explicit operator string(CSon value) => value.StringValue;
        public static explicit operator short?(CSon value) => value.ShortValue;
        public static explicit operator ushort?(CSon value) => value.UShortValue;
        public static explicit operator int?(CSon value) => value.IntValue;
        public static explicit operator uint?(CSon value) => value.UIntValue;
        public static explicit operator long?(CSon value) => value.LongValue;
        public static explicit operator ulong?(CSon value) => value.ULongValue;
        public static explicit operator float?(CSon value) => value.FloatValue;
        public static explicit operator double?(CSon value) => value.DoubleValue;
        public static explicit operator decimal?(CSon value) => value.DecimalValue;
        public static explicit operator DateTime?(CSon value) => value.DateTimeValue;
             
        /// <summary>
        /// 判断是否为空
        /// </summary>
        public bool IsCSonNull
        {
            get
            {
                switch (CSonType)
                {
                    case CSonTypes.CObject:
                        return _kvs == null;
                    case CSonTypes.CArray:
                        return _array == null;
                    case CSonTypes.Value:
                        return _bvalue == null;
                }
                return false;
            }
        }
        /// <summary>
        /// 获取或设置字节值，仅为Value时有效
        /// </summary>
        public byte? ByteValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : _bvalue[0];
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 0;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = new byte[] { value.Value };
            }
        }
        /// <summary>
        /// 获取或设置字节数组值，仅为Value时有效
        /// </summary>
        public byte[] BytesValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue;
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 1;
                _bvalue = value;
            }
        }
        /// <summary>
        /// 获取或设置布尔值，仅为Value时有效
        /// </summary>
        public bool? BooleanValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToBoolean(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 2;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置字符串值，仅为Value时有效
        /// </summary>
        public string StringValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? string.Empty : Encoding.UTF8.GetString(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 3;
                _bvalue = Encoding.UTF8.GetBytes(value);
            }
        }
        /// <summary>
        /// 获取或设置短整型值，仅为Value时有效
        /// </summary>
        public short? ShortValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToInt16(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 4;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置无符号短整型值，仅为Value时有效
        /// </summary>
        public ushort? UShortValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToUInt16(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 5;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置整型值，仅为Value时有效
        /// </summary>
        public int? IntValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToInt32(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 6;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置无符号整形值，仅为Value时有效
        /// </summary>
        public uint? UIntValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToUInt32(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 7;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置长整型值，仅为Value时有效
        /// </summary>
        public long? LongValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToInt64(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 8;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置无符号长整型值，仅为Value时有效
        /// </summary>
        public ulong? ULongValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToUInt64(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 9;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置浮点值，仅为Value时有效
        /// </summary>
        public float? FloatValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToSingle(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 10;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置双精度浮点值，仅为Value时有效
        /// </summary>
        public double? DoubleValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : BitConverter.ToDouble(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 11;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置Decimal值
        /// </summary>
        public decimal? DecimalValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : ToDecimal(_bvalue);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 12;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = ToBytes(value.Value);
            }
        }
        /// <summary>
        /// 获取或设置日期值
        /// </summary>
        public DateTime? DateTimeValue
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.Value)
                        throw new Exception("CSonType不是Value类型~");

                    return _bvalue == null ? null : new DateTime(BitConverter.ToInt64(_bvalue));
                }
                catch (Exception)
                {
                    throw;
                }
            }
            set
            {
                if (CSonType != CSonTypes.Value)
                    throw new Exception("CSonType不是Value类型~");

                _valueType = 13;
                if (value == null)
                    _bvalue = null;
                else
                    _bvalue = BitConverter.GetBytes(value.Value.Ticks);
            }
        }

        public object ObjectValue
        {
            get
            {
                switch (_valueType)
                {
                    case 0:
                        return _bvalue[0];
                    case 1:
                        return _bvalue;
                    case 2:
                        return BitConverter.ToBoolean(_bvalue);
                    case 3:
                        return Encoding.UTF8.GetString(_bvalue);
                    case 4:
                        return BitConverter.ToInt16(_bvalue);
                    case 5:
                        return BitConverter.ToUInt16(_bvalue);
                    case 6:
                        return BitConverter.ToInt32(_bvalue);
                    case 7:
                        return BitConverter.ToUInt32(_bvalue);
                    case 8:
                        return BitConverter.ToInt64(_bvalue);
                    case 9:
                        return BitConverter.ToUInt64(_bvalue);
                    case 10:
                        return BitConverter.ToSingle(_bvalue);
                    case 11:
                        return BitConverter.ToDouble(_bvalue);
                    case 12:
                        return ToDecimal(_bvalue);
                    case 13:
                        return new DateTime(BitConverter.ToInt64(_bvalue));
                }
                return null;
            }
        }

        /******************************* 作为键值对时 **********************************/
        private List<KV> _kvs = null;

        /// <summary>
        /// 获取一个键值对的值，仅为CObject时有效
        /// </summary>
        /// <param name="key"></param>
        /// <returns>当key存在时，返回对应的值，当key不存在时，返回CSonValueNull</returns>
        public CSon this[string key]
        {
            get
            {
                try
                {
                    if (CSonType != CSonTypes.CObject)
                        throw new Exception("CSonType不是键值对~");

                    if (_kvs == null)
                        return CSonValueNull;
                    else
                    {
                        foreach (var item in _kvs)
                        {
                            if (item.Key == key)
                                return item.Value;
                        }
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                return null;
            }
        }

        /// <summary>
        /// 获取所有键，仅当CSonType为CObject时有效
        /// </summary>
        public string[] Keys
        {
            get
            {
                string[] keys = null;
                try
                {
                    if (CSonType != CSonTypes.CObject)
                        return keys;
                    if (_kvs.IsNullOrEmpty())
                        return keys;

                    keys = new string[_kvs.Count];

                    for (int i = 0; i < _kvs.Count; i++)
                        keys[i] = _kvs[i].Key;
                }
                catch (Exception)
                {
                    throw;
                }
                return keys;
            }
        }

        /// <summary>
        /// 获取所有值，当CSonType为CSonTypes.CObject时，返回所有key对应的值，
        /// 当为CArray时，返回所有的数组对象
        /// </summary>
        public CSon[] Values
        {
            get
            {
                if (CSonType == CSonTypes.CObject)
                {
                    return _kvs.IsNullOrEmpty() ? null : _kvs.Select(x => x.Value).ToArray();
                }
                else if (CSonType == CSonTypes.CArray)
                {
                    return _array.IsNullOrEmpty() ? null : _array.ToArray();
                }
                else
                    throw new Exception("仅当CSonType为CSonTypes.CObject或CSonTypes.CArray时有效");
            }
        }

        /// <summary>
        /// 添加一个键值对，如果key已存在，则更新，并返回true，如果key不存在，添加并返回false
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Add(string key, CSon value)
        {
            bool res = false;
            try
            {
                try
                {
                    if (CSonType != CSonTypes.CObject)
                        throw new Exception("CSonType不是键值对~");
                    if (value == null)
                        throw new Exception("value不能为null,请用替代");

                    _kvs = _kvs == null ? new List<KV>() : _kvs;

                    foreach (var item in _kvs)
                    {
                        if (item.Key == key)
                        {
                            item.Value = value;
                            res = true;
                            break;
                        }
                    }

                    //如果没有添加
                    if (res == false)
                        _kvs.Add(new KV(key, value));
                }
                catch (Exception)
                {
                    throw;
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 删除，如果key已存在，返回true，如果key不存在，不报错，但返回false
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Remove(string key)
        {
            bool res = false;
            try
            {
                try
                {
                    if (CSonType != CSonTypes.CObject)
                        throw new Exception("CSonType不是键值对~");
                    if (_kvs.IsNullOrEmpty())
                        return res;

                    KV val = null;
                    foreach (var item in _kvs)
                    {
                        if (item.Key == key)
                        {
                            val = item;
                            res = true;
                            break;
                        }
                    }

                    if (val != null)
                    {
                        _kvs.Remove(val);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 是否包含键
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool IsContainKey(string key)
        {
            bool res = false;
            try
            {
                if (CSonType != CSonTypes.CObject)
                    throw new Exception("CSonType不是键值对~");
                if (_kvs.IsNullOrEmpty())
                    return res;

                foreach (var item in _kvs)
                {
                    if (item.Key == key)
                    {
                        res = true;
                        break;
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /******************************* 作为数组时 **********************************/
        private List<CSon> _array = null;

        /// <summary>
        /// 获取指定索引处的值，仅为CObject或CArray时有效
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public CSon this[int index]
        {
            get
            {
                try
                {
                    if (CSonType == CSonTypes.CObject)
                    {
                        //如果是键值对
                        if (_kvs.IsNullOrEmpty())
                            throw new Exception("索引超出范围~");
                        if (index > _kvs.Count - 1)
                            throw new Exception("索引超出范围~");
                        if (index < 0)
                            throw new Exception("无效的索引~");

                        return _kvs[index].Value;
                    }
                    else
                    {
                        if (_array.IsNullOrEmpty())
                            throw new Exception("索引超出范围~");
                        if (index > _array.Count - 1)
                            throw new Exception("索引超出范围~");
                        if (index < 0)
                            throw new Exception("无效的索引~");

                        return _array[index];
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        /// <summary>
        /// 添加一个项，仅为CArray时有效
        /// </summary>
        /// <param name="value"></param>
        public void Add(CSon value)
        {
            try
            {
                if (CSonType != CSonTypes.CArray)
                    throw new Exception("CSonType不是数组~");

                _array = _array == null ? new List<CSon>() : _array;
                _array.Add(value);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 删除一个项，仅为CArray时有效
        /// </summary>
        /// <param name="value"></param>
        public void Remove(CSon value)
        {
            try
            {
                if (CSonType != CSonTypes.CArray)
                    throw new Exception("CSonType不是数组~");

                if (_array.IsNullOrEmpty() == false)
                    _array.Remove(value);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /******************************* 公共 **********************************/
        /// <summary>
        /// 将本身转换为字节流
        /// 第一个字节表示类型，0值，1键值对，2数组
        /// 2-5：长度
        /// 6-N：如果是值类型，存放实际的值
        ///      如果是键值对，则为键值对的数据，键值对的key长度为一个字节，最大127，也用四个字节太浪费了
        ///      如果是数组，则为数组的数据
        /// </summary>
        /// <returns></returns>
        public byte[] ToBytes()
        {
            try
            {
                List<byte> res = new List<byte>();
                ToBytesList(ref res);
                return res.ToArray();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 将本对象转换为字节列表
        /// </summary>
        /// <param name="source">如果source为空，初始化一个新的list作为结果，如果source不为空，则将结果追加到source末尾</param>
        /// <returns></returns>
        public void ToBytesList(ref List<byte> source)
        {
            source = source == null ? new List<byte>() : source;
            try
            {
                int offset = source.Count;
                if (CSonType == CSonTypes.CArray)
                {
                    //如果是数组
                    source.Add(0x02);
                    source.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00 });        //长度占位

                    //遍历数组中的每个元素，将每个元素转换为字节数组
                    if (_array.IsNullOrEmpty() == false)
                    {
                        for (int i = 0; i < _array.Count; i++)
                        {
                            _array[i].ToBytesList(ref source);
                        }
                    }

                    byte[] length = BitConverter.GetBytes(source.Count - 5 - offset);
                    CopyArray(ref length, ref source, offset);
                }
                else if (CSonType == CSonTypes.CObject)
                {
                    //如果是键值对
                    source.Add(0x01);
                    source.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00 });

                    //遍历每个键值对，将每个键值对转换为字节数组
                    if (_kvs.IsNullOrEmpty() == false)
                    {
                        foreach (var kv in _kvs)
                        {
                            //转换KEY
                            byte[] b = Encoding.UTF8.GetBytes(kv.Key);
                            source.Add((byte)(b.Length & 0xFF));
                            source.AddRange(b);

                            //转换值
                            kv.Value.ToBytesList(ref source);
                        }
                    }

                    byte[] length = BitConverter.GetBytes(source.Count - 5 - offset);
                    CopyArray(ref length, ref source, offset);
                }
                else if (CSonType == CSonTypes.Value)
                {
                    //如果是值
                    source.Add(0x00);
                    if (_bvalue == null)
                        source.AddRange(BitConverter.GetBytes(int.MaxValue));          //字段长度
                    else
                    {
                        source.AddRange(BitConverter.GetBytes(_bvalue.Length));        //字段长度
                        source.AddRange(_bvalue);                                      //字段值
                        source.Add(_valueType);                                        //字段类型
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 将字节数组转换为CSon
        /// </summary>
        /// <param name="data">用ref是为了提高效率，省略拷贝字节数组的过程</param>
        /// <returns></returns>
        public static CSon Parse(Span<byte> data, ref int position, int length = -1)
        {
            CSon res = null;
            try
            {
                if (data == null)
                    return res;
                if (data.Length < 2)
                    return res;

                if (length == -1)
                    length = data.Length - position;

                int endIndex = position + length - 1;
                int l = 0;                                      //内部用的长度

                //byte[] b = null;

                if (data[position] == 0x02)
                {
                    position += 1;

                    //如果是数组
                    res = new CSon(CSonTypes.CArray);

                    //长度
                    l = BitConverter.ToInt32(data.Slice(position, 4));
                    position += 4;

                    //转换数组中的每一项
                    while (position < endIndex)
                    {
                        int subLength = BitConverter.ToInt32(data.Slice(position + 1, 4));      //每一项的第一个字节表示类型，所以要+1
                        CSon csonItem = Parse(data, ref position, 5 + subLength);
                        res.Add(csonItem);
                    }
                }
                else if (data[position] == 0x01)
                {
                    position += 1;

                    //如果是键值对
                    res = new CSon(CSonTypes.CObject);

                    //长度
                    l = BitConverter.ToInt32(data.Slice(position, 4));
                    position += 4;

                    while (position < endIndex)
                    {
                        //key
                        int keyLength = data[position];
                        position += 1;
                        string key = Encoding.UTF8.GetString(data.Slice(position, keyLength));
                        position += keyLength;

                        //value
                        int subLength = BitConverter.ToInt32(data.Slice(position + 1, 4));
                        CSon value = Parse(data, ref position, 5 + subLength);
                        res.Add(key, value);
                    }
                }
                else if (data[position] == 0x00)
                {
                    position += 1;

                    //如果是值
                    //长度
                    l = BitConverter.ToInt32(data.Slice(position, 4));
                    position += 4;

                    //值
                    if (l == int.MaxValue)
                    {
                        res = CSonValueNull;
                    }
                    else
                    {
                        res = new CSon(data.Slice(position, l).ToArray());
                        position += l;
                        res._valueType = data[position];
                        position += 1;
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        private static void CopyArray(ref byte[] source, ref List<byte> dest, int destOffset)
        {
            try
            {
                for (int i = 0; i < 4; i++)
                    dest[destOffset + i + 1] = source[i];
            }
            catch (Exception)
            {
                throw;
            }
        }

        private static byte[] CopyArray(ref byte[] source,int startIndex,int length)
        {
            byte[] res = new byte[length];
            try
            {
                for (int i = startIndex; i < startIndex + length; i++)
                    res[i - startIndex] = source[i];
            }
            catch (Exception)
            {

                throw;
            }
            return res;
        }

        private static byte[] ToBytes(decimal value)
        {
            byte[] res = new byte[16];
            try
            {
                int[] intVal = decimal.GetBits(value);
                for(int i = 0; i < 4; i++)
                {
                    byte[] b = BitConverter.GetBytes(intVal[i]);
                    for(int j = 0; j < 4; j++)
                    {
                        res[i * 4 + j] = b[j];
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        private static decimal ToDecimal(byte[] data)
        {
            decimal res = 0;
            try
            {
                int[] bits = new int[4];
                for(int i = 0; i < 4; i++)
                {
                    bits[i] = BitConverter.ToInt32(data, i * 4);
                }
                res = new decimal(bits);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 将对象转换为CSon，仅支持部分.net的基础类型，如果遇到不支持的类型，抛错；慎用，目前该函数主要用于数据库orm
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static CSon ToCSon(object data)
        {
            CSon res = null;
            try
            {
                if (data == null)
                    res = CSonValueNull;
                else
                {
                    var t = data.GetType();
                    switch (t.Name)
                    {
                        case "Byte":
                            res = (byte)data;
                            break;
                        case "Boolean":
                            res = (bool)data;
                            break;
                        case "String":
                            res = data.ToString();
                            break;
                        case "DateTime":
                            res = (DateTime)data;
                            break;
                        case "Decimal":
                            res = new CSon(ToBytes((decimal)data)) { _valueType = 12 };
                            break;
                        case "Int16":
                            res = (short)data;
                            break;
                        case "UInt16":
                            res = (ushort)data;
                            break;
                        case "Int32":
                            res = (int)data;
                            break;
                        case "UInt32":
                            res = (uint)data;
                            break;
                        case "Int64":
                            res = (long)data;
                            break;
                        case "UInt64":
                            res = (ulong)data;
                            break;
                        case "Single":
                            res = (float)data;
                            break;
                        case "Double":
                            res = (double)data;
                            break;
                        default:
                            throw new Exception($"CSon暂不支持该种类型的数据转换[{t.Name}]");
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }
    }

    internal class KV
    {
        public string Key { get; set; }

        public CSon Value { get; set; }

        public KV(string key, CSon value)
        {
            Key = key;
            Value = value;
        }
    }

    public class CSonValueNull { }
    public class CSonObjectNull { }
    public class CSonArrayNull { }
}
